﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;

namespace MaxLeaf.Common
{

    /// <summary>
    /// 数据库信息
    /// </summary>
    public class ServerInfo
    {
        public string Name { get; private set; }
        public string IP { get; private set; }
        public string Port { get; private set; }
        private string _strDatabase = string.Empty;
        public string Database
        {
            get
            {
                return _strDatabase;
            }

            private set
            {
                if (_strDatabase.Equals("mary", StringComparison.InvariantCultureIgnoreCase) && !value.Equals("mary", StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new Exception(_strDatabase+"_"+value);
                }
                _strDatabase = value;
            }
        }
        public string Uid { get; private set; }
        public string Pwd { get; private set; }
        public ServerType Type { get; private set; }       //用来判断是K3的还是网站的 
        private bool _blnMasterDB = false;
        public bool MasterDB { 
            get{
                if (Name.Equals("mary", StringComparison.InvariantCultureIgnoreCase) && !_blnMasterDB)
                {
                    throw new Exception(_blnMasterDB.ToString());
                }
                return _blnMasterDB;
            }
            private set
            {
                if (Name.Equals("mary", StringComparison.InvariantCultureIgnoreCase ) && !value)
                {
                    throw new Exception(_blnMasterDB.ToString ());
                }
                _blnMasterDB = value;
                    
            }
        }   //是不是K3的主帐套
        private string _strAcctType = string.Empty;
        public string AcctType
        {
            get
            {

                return _strAcctType;
            }
            private set
            {

                _strAcctType = value;

            }
        }   //帐套类型：mary,bj,wh
        public List<string> CityDBs { get; private set; }   //分帐套数据库

        private static Dictionary<ServerType, List<ServerInfo>> mdictServers = new Dictionary<ServerType, List<ServerInfo>>();
        public static void Init(string strFileName)
        {
            LogManager.Debug("Init" + strFileName);
            XmlDocument xml = new XmlDocument();


            xml.Load(strFileName);
            if (HttpContext.Current != null)
            {
                HttpContext.Current.Application[Enum.GetName(typeof(ServerType), ServerType.K3)] = GetServers(xml, "K3Servers");
                HttpContext.Current.Application[Enum.GetName(typeof(ServerType), ServerType.Web)] = GetServers(xml, "WebServers");
            }
            else
            {
                mdictServers = new Dictionary<ServerType, List<ServerInfo>>();
                mdictServers.Add( ServerType.K3, GetServers(xml, "K3Servers"));
                mdictServers.Add(ServerType.Web, GetServers(xml, "WebServers"));
            }
        }

        private static List<ServerInfo> GetServers(XmlDocument xml, string strType)
        {
            List<ServerInfo> lst = new List<ServerInfo>();

            XmlNode parent = xml.SelectSingleNode("//" + strType);

            foreach (XmlNode node in parent.ChildNodes)
            {
                ServerInfo server = GetServer(node);
                if (server.Type == ServerType.K3 && server.MasterDB)
                {
                    //加载分帐套
                    server.CityDBs = GetCityDBs(node);
                }
                lst.Add(server);
            }

            return lst;
        }

        private static List<string> GetCityDBs(XmlNode xml)
        {
            XmlNode parent = xml.SelectSingleNode("//CityDBs");
            List<string> lstDBs = new List<string>();
            foreach (XmlNode node in parent.ChildNodes)
            {
                if (node is XmlComment)
                {
                    continue;
                }
                lstDBs.Add(node.Attributes["database"].Value.ToString().ToUpper());
            }

            return lstDBs;
        }

        private static ServerInfo GetServer(XmlNode node)
        {
            LogManager.Debug(node.Attributes["name"].Value.ToString() +";"+node.Attributes["MasterDB"].Value.ToString());
            return  new ServerInfo(node.Attributes["name"].Value.ToString()
                ,node.Attributes["ip"].Value.ToString()
                ,node.Attributes["port"].Value.ToString()
                ,node.Attributes["database"].Value.ToString()
                ,node.Attributes["uid"].Value.ToString()
                ,node.Attributes["pwd"].Value.ToString()
                ,(node.Attributes["type"].Value.ToString() == "K3" ? ServerType.K3 : ServerType.Web)
                ,CvtFunc.ToBoolean( node.Attributes["MasterDB"].Value.ToString())
                , (CvtFunc.ToBoolean(node.Attributes["MasterDB"].Value.ToString()) ? node.Attributes["AcctType"].Value.ToString().ToLower(): string.Empty)
                );

           
        }

        private ServerInfo()
        {
        }
        private ServerInfo(string Name, string IP, string Port, string Database, string Uid, string Pwd, ServerType Type, bool MasterDB,string AcctType)
        {
            this.Name = Name;
            this.IP = IP;
            this.Port = Port;
            this.Database = Database;
            this.Uid = Uid;
            this.Pwd = Pwd;
            this.Type = Type;
            this.MasterDB = MasterDB;
            this.AcctType = AcctType;
        }
        

        public static List<ServerInfo> GetServers(ServerType serverType)
        {
            List<ServerInfo> lst = null;
            if (serverType == ServerType.All)
            {
                lst = new List<ServerInfo>();
                lst.AddRange(GetServers(ServerType.K3));
                lst.AddRange(GetServers(ServerType.Web) );
            }
            else
            {
                if (HttpContext.Current != null)
                {
                    lst = (List<ServerInfo>)HttpContext.Current.Application[Enum.GetName(typeof(ServerType), serverType)];
                }
                else
                {
                    lst = mdictServers[serverType];
                }
            }
            return lst;
        }

        public static List<ServerInfo> GetServers(ServerType serverType, string strServerName)
        {
            

            if (strServerName.Length == 0 || strServerName.Equals("All", StringComparison.InvariantCultureIgnoreCase))
            {
                List<ServerInfo> lst = GetServers(serverType);
                return lst;
            }
            else
            {
                List<ServerInfo> lst =new List<ServerInfo>();
                lst.Add(GetServer(serverType,strServerName ));
                return lst;
            }
        }
        public static ServerInfo GetServer(  string strServerName)
        {
            return GetServer(ServerType.All, strServerName);
        }
        public static ServerInfo GetServer(ServerType serverType,string strServerName)
        {
            List<ServerInfo> lst = GetServers(serverType);

            return GetServer(lst,strServerName);

        }


        public static ServerInfo GetK3MasterServer()
        {
            List<ServerInfo> lst = GetServers(ServerType.K3 );
             
            return GetK3MasterServer(lst);
        }
        public static ServerInfo GetK3MasterServer(List<ServerInfo> lst)
        {
            
            foreach (ServerInfo server in lst)
            {
                if (server.MasterDB  && server.Type== ServerType.K3 )
                {
                    return server;
                }
            }
            return null;
        }
        private static ServerInfo GetServer(List<ServerInfo> lst, string strServerName)
        {
            
            if (strServerName.Length == 0)
            {
                return GetK3MasterServer(lst);
            }

            foreach (ServerInfo server in lst)
            {
                if (server.Name.Equals(strServerName, StringComparison.InvariantCultureIgnoreCase))
                {
                    return server;
                }
            }

            return null;
        }

        private static object _lockObj = new object();
        private bool _log
        {
            get
            {
                if (HttpContext.Current.Application[this.ToString()]==null)
                {
                    HttpContext.Current.Application[this.ToString()] = false;
                }
                return (bool)HttpContext.Current.Application[this.ToString()];
            }
            set
            {
                if (HttpContext.Current.Application[this.ToString()] == null)
                {
                    HttpContext.Current.Application[this.ToString()] = false;
                }
                HttpContext.Current.Application[this.ToString()] = value;
            }
        }
        public bool CheckingLog()
        {
            lock (_lockObj)
            {
                if (_log)
                {
                    LogManager.Debug("A"+_log.ToString());
                    return true;
                }
                _log = true;
                LogManager.Debug("B" + _log.ToString());
                return false;
            }
        }

        public void CheckedLog()
        {
            lock (_lockObj)
            { 
                _log = false;
                LogManager.Debug("C" + _log.ToString());
            }
        }


        public override string ToString()
        {

            return string.Format("Server:{0}_{1}_{2}_{3}",this.Name,this.Database,this.MasterDB,this.AcctType);
        }


        public static ServerInfo GetK3ServerByDBName(  string strDBName)
        {
            if (strDBName.Length == 0)
            {
                return GetK3MasterServer();
            }
            foreach (ServerInfo server in GetServers( ServerType.K3))
            {
                if (server.Database.Equals(strDBName, StringComparison.InvariantCultureIgnoreCase))
                {
                    return server;
                }
            }

            return CreateK3ChildServer(strDBName);
        }

        public static ServerInfo CreateK3ChildServer(string strDBName)
        {
            ServerInfo server = ServerInfo.GetK3MasterServer();

            return CreateK3ChildServer(server, strDBName);
        }

        public static ServerInfo CreateK3ChildServer(ServerInfo server,string strDBName)
        {
            
            return new ServerInfo(strDBName
                , server.IP
                , server.Port
                , strDBName
                , server.Uid
                , server.Pwd
                , server.Type
                , false
                , server.AcctType
                );
        }
               

        public static IEnumerable<ServerInfo> GetCityServers(ServerInfo K3MsterServer, List<string> lstDBs)
        {
            List<ServerInfo> lstServers = new List<ServerInfo>();
            foreach (string strDB in lstDBs)
            {
                if (K3MsterServer.CityDBs.Contains(strDB.ToUpper()))
                {
                    lstServers.Add(CreateK3ChildServer(K3MsterServer, strDB));
                }
            }

            return lstServers;
        }
    }
}